/******************************************************************************
* Copyright (C) 2018, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file main.c
 **
 ** A detailed description is available at
 ** @link Sample Group Some description @endlink
 **
 **   - 2018-05-08  1.0  Lux First version for Device Driver Library of Module.
 **
 ******************************************************************************/

/******************************************************************************
 * Include files
 ******************************************************************************/
#include "ddl.h"
#include "timer3.h"
#include "gpio.h"
#include "spi.h"
#include "SI24R1.h"

/******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/

/******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/******************************************************************************
 * Local variable definitions ('static')                                      *
 ******************************************************************************/
    static uint8_t buf_rf24[32] = {0};
/******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/

/*****************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/

/**
 ******************************************************************************
 ** \brief  初始化外部GPIO引脚
 **
 ** \return 无
 ******************************************************************************/
static void App_RF24Init(void)
{
    stc_gpio_cfg_t GpioInitStruct;
    DDL_ZERO_STRUCT(GpioInitStruct);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);

    //SPI0引脚配置:主机
    GpioInitStruct.enDrv = GpioDrvH;
    GpioInitStruct.enDir = GpioDirOut;

    Gpio_Init(PORT_RF24_MOSI, PIN_RF24_MOSI,&GpioInitStruct);
    Gpio_SetAfMode(PORT_RF24_MOSI, PIN_RF24_MOSI,GpioAf1);        //配置引脚PB5作为SPI0_MOSI

    Gpio_Init(PORT_RF24_CS_N, PIN_RF24_CS_N,&GpioInitStruct);
    Gpio_SetAfMode(PORT_RF24_CS_N, PIN_RF24_CS_N,GpioAf1);         //配置引脚PA14作为SPI0_CS

    Gpio_Init(PORT_RF24_SCK, PIN_RF24_SCK,&GpioInitStruct);
    Gpio_SetAfMode(PORT_RF24_SCK, PIN_RF24_SCK,GpioAf1);         //配置引脚PB03作为SPI0_SCK

    GpioInitStruct.enDir = GpioDirIn;
    Gpio_Init(PORT_RF24_MISO, PIN_RF24_MISO,&GpioInitStruct);
    Gpio_SetAfMode(PORT_RF24_MISO, PIN_RF24_MISO,GpioAf1);         //配置引脚PB04作为SPI0_MISO


    ///< 端口方向配置->输入
    GpioInitStruct.enDir = GpioDirIn;
    ///< 端口驱动能力配置->高驱动能力
    GpioInitStruct.enDrv = GpioDrvL;
    ///< 端口上下拉配置->无
    GpioInitStruct.enPu = GpioPuDisable;
    GpioInitStruct.enPd = GpioPdDisable;
    ///< 端口开漏输出配置->开漏输出关闭
    GpioInitStruct.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    GpioInitStruct.enCtrlMode = GpioAHB;

      //PB6: RF24 PIN IRQ#  
    GpioInitStruct.enPu = GpioPuEnable;  //配置为上拉
    Gpio_Init(PORT_RF24_IRQ, PIN_RF24_IRQ, &GpioInitStruct);
    
    
    
    
      //PB7: RF24 CE PIN
    GpioInitStruct.enDrv  = GpioDrvH;
    GpioInitStruct.enDir  = GpioDirOut;
    Gpio_Init(PORT_RF24_CE, PIN_RF24_CE, &GpioInitStruct);
    Gpio_WriteOutputIO(PORT_RF24_CE, PIN_RF24_CE, FALSE);     //关闭RF模块
}

/**
 ******************************************************************************
 ** \brief  初始化SPI
 **
 ** \return 无
 ******************************************************************************/
static void App_SPIInit(void)
{
    stc_spi_cfg_t  SpiInitStruct;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi0,TRUE);

    //SPI0模块配置：主机
    SpiInitStruct.enSpiMode = SpiMskMaster;   //配置位主机模式
    SpiInitStruct.enPclkDiv = SpiClkMskDiv128;  //波特率：fsys/128
    SpiInitStruct.enCPHA    = SpiMskCphafirst;//第一边沿采样
    SpiInitStruct.enCPOL    = SpiMskcpollow;  //极性为低
    Spi_Init(M0P_SPI0, &SpiInitStruct);
}

static void App_LedInit(void)
{
    stc_gpio_cfg_t stcGpioCfg;
    
    ///< 打开GPIO外设时钟门控
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); 
    
    ///< 端口方向配置->输出(其它参数与以上（输入）配置参数一致)
    stcGpioCfg.enDir = GpioDirOut;
    ///< 端口上下拉配置->下拉
    stcGpioCfg.enPu = GpioPuDisable;
    stcGpioCfg.enPd = GpioPdEnable;
    
    ///< LED关闭
    Gpio_ClrIO(PORT_LED, PIN_LED);
    
    ///< GPIO IO LED端口初始化
    Gpio_Init(PORT_LED, PIN_LED, &stcGpioCfg);
    

}


static void App_UserKeyInit(void)
{
    stc_gpio_cfg_t stcGpioCfg;
    
    ///< 打开GPIO外设时钟门控
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    
    ///< 端口方向配置->输入
    stcGpioCfg.enDir = GpioDirIn;
    ///< 端口驱动能力配置->高驱动能力
    stcGpioCfg.enDrv = GpioDrvL;
    ///< 端口上下拉配置->无
    stcGpioCfg.enPu = GpioPuDisable;
    stcGpioCfg.enPd = GpioPdDisable;
    ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    stcGpioCfg.enCtrlMode = GpioAHB;
    ///< GPIO IO USER KEY初始化
    Gpio_Init(PORT_KEY, PIN_KEY, &stcGpioCfg); 
}

//Timer3 配置
void App_Timer3Cfg(uint16_t u16Period)
{
    uint16_t                  u16ArrValue;
    uint16_t                  u16CntValue;
    stc_tim3_mode0_cfg_t   stcTim3BaseCfg;
    
    //结构体初始化清零
    DDL_ZERO_STRUCT(stcTim3BaseCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Timer3外设时钟使能
    
    stcTim3BaseCfg.enWorkMode = Tim3WorkMode0;               //定时器模式
    stcTim3BaseCfg.enCT       = Tim3Timer;                   //定时器功能，计数时钟为内部PCLK
    stcTim3BaseCfg.enPRS      = Tim3PCLKDiv16;               //PCLK/16
    stcTim3BaseCfg.enCntMode  = Tim316bitArrMode;            //自动重载16位计数器/定时器
    stcTim3BaseCfg.bEnTog     = TRUE;
    stcTim3BaseCfg.bEnGate    = FALSE;
    stcTim3BaseCfg.enGateP    = Tim3GatePositive;
    
    Tim3_Mode0_Init(&stcTim3BaseCfg);                        //TIM3 的模式0功能初始化
        
    u16ArrValue = 0x10000 - u16Period;
    Tim3_M0_ARRSet(u16ArrValue);                             //设置重载值
    
    u16CntValue = 0x10000 - u16Period;
    Tim3_M0_Cnt16Set(u16CntValue);                           //设置计数初值
    
//    Tim3_ClearIntFlag(Tim3UevIrq);                         //清中断标志
//    EnableNvic(TIM3_IRQn, 3, TRUE);                        //TIM3 开中断
//    Tim3_Mode0_EnableIrq();                                //使能TIM3中断(模式0时只有一个中断)    
    
    Tim3_M0_Enable_Output(TRUE);                             //TIM3 端口输出使能
}

//Timer3 CHx 端口配置
void App_BuzzerPortCfg(void)
{
    stc_gpio_cfg_t         stcTIM3Port;
    
    //结构体初始化清零
    DDL_ZERO_STRUCT(stcTIM3Port);
    
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //GPIO 外设时钟使能
    
    stcTIM3Port.enDir  = GpioDirOut;
    //PA08设置为TIM3_CH0A
    Gpio_Init(GpioPortA, GpioPin8, &stcTIM3Port);
    Gpio_SetAfMode(GpioPortA,GpioPin8,GpioAf2);
    
    //PA07设置为TIM3_CH0B
//    Gpio_Init(GpioPortA, GpioPin7, &stcTIM3Port);
//    Gpio_SetAfMode(GpioPortA,GpioPin7,GpioAf4);
}

/**
 ******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 ** This sample
 **
 ******************************************************************************/
int32_t main(void)
{
    uint16_t cnt = 0;
    ///< 按键端口初始化
    App_UserKeyInit();
    
    ///< 2.4G RF模块端口初始化
    App_RF24Init();
    
    ///< SPI初始化
    App_SPIInit();
    
    ///< 蜂鸣器端口初始化
    App_BuzzerPortCfg();
    ///< LED端口初始化
    App_LedInit();
 
    //App_Timer3Cfg(25000); //Timer3 配置; 16分频,周期25000-->25000*(1/4M) * 16 = 100000us = 100ms
    App_Timer3Cfg(250); //Timer3 配置; 16分频,周期25000-->25000*(1/4M) * 16 = 100000us = 1ms
    ///< 打开并配置USER KEY为下降沿中断
    Gpio_EnableIrq(PORT_KEY, PIN_KEY, GpioIrqFalling);
    ///< 打开并配置RF24模块的IRQ脚为下降沿中断
    Gpio_EnableIrq(PORT_RF24_IRQ, PIN_RF24_IRQ, GpioIrqFalling);    
    
    
    
	SI24R1_RX_Mode();
    
    ///< 使能端口PORTA系统中断
    EnableNvic(PORTA_IRQn, IrqLevel3, TRUE);
    
    ///< 使能端口PORTB系统中断
    EnableNvic(PORTB_IRQn, IrqLevel3, TRUE);
    
    Tim3_M0_Stop();        //TIM3 运行。
    while(1)
    {
        if(!SI24R1_RxPacket(buf_rf24)){
			switch(buf_rf24[0])
			{
				case 0x55:{
                    for(cnt = 0; cnt < 20; cnt++){
                        Gpio_SetIO(PORT_LED, PIN_LED);
                        Tim3_M0_Run();
                        delay1ms(300);
                        Gpio_ClrIO(PORT_LED, PIN_LED);
                        Tim3_M0_Stop();
                        delay1ms(300);                    
                    }      
                }

					break;
				default:
					break;
			}
			buf_rf24[0] = 0;	        
       } 
        ;
    }
}

/*******************************************************************************
 * TIM3中断服务函数
 ******************************************************************************/
void Tim3_IRQHandler(void)
{
     //Timer3 模式0 计数溢出中断，可在Timer3 配置函数中使能中断
     if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
     {
         
        Tim3_ClearIntFlag(Tim3UevIrq);
     }
}


///< PortA中断服务函数:userkey 用户按键
void PortA_IRQHandler(void)
{
    if(TRUE == Gpio_GetIrqStatus(PORT_KEY, PIN_KEY))
    {     
        buf_rf24[0] = 0x55;
        SI24R1_TX_Mode();
        SI24R1_TxPacket(buf_rf24);
        delay1ms(200);
        //buf_rf24[0] = 0;
        SI24R1_RX_Mode();
//        ///< LED点亮
//        Gpio_SetIO(PORT_LED, PIN_LED);
//        
//        delay1ms(2000);
//        
//        ///< LED关闭
//        Gpio_ClrIO(PORT_LED, PIN_LED);  

        Gpio_ClearIrq(PORT_KEY, PIN_KEY);    
    }

}  

///< PortB中断服务函数:RF24模块消息通知
void PortB_IRQHandler(void)
{
    if(TRUE == Gpio_GetIrqStatus(PORT_RF24_IRQ, PIN_RF24_IRQ))
    {        
       
        Gpio_ClearIrq(PORT_RF24_IRQ, PIN_RF24_IRQ);    
    }

} 

/******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/


